using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;

namespace ProgrammingLanguageNr1
{
	public class AST
	{
		public AST () {
		}
		
		public AST (Token token)
		{
			m_token = token;
		}
		
		public Token.TokenType getTokenType() { 
			if (m_token != null) {
				return m_token.getTokenType(); 
			} else {
				return Token.TokenType.NO_TOKEN_TYPE;
			}
		}
		
		public bool isNil() { return m_token == null; }
		
		public void addChild(AST childTree) {
			Assert.IsNotNull(childTree);
			
			allocateListIfNecessary();
			m_children.Add(childTree);
		}
		
		private void allocateListIfNecessary() {
			if (m_children == null) {
				m_children = new List<AST>();
			}
		}
		
		public void addChild(Token token) {
			AST childTree = new AST(token);
			addChild(childTree);
		}
		
		public AST getChild(int n) {
			allocateListIfNecessary();
			Assert.IsTrue(n >= 0);
			Assert.IsTrue(n < m_children.Count);
			AST child = m_children[n];
			Assert.IsNotNull(child);
			return child;
		}
		
		public List<AST> getChildren() {
			allocateListIfNecessary();
			return m_children;
		}
		
		public string getTokenString() {
			return m_token != null ? m_token.getTokenString() : "nil";
		}
		
		public Token getToken() {
			return m_token;
		}
		
		public string getTreeAsString() {
			if (m_children == null || m_children.Count == 0) {
				return getTokenString();
			}
			StringBuilder stringTree = new StringBuilder();
			if ( !isNil() ) {
				stringTree.Append("(");
				stringTree.Append(getTokenString());
				stringTree.Append(" ");
			}
			int i = 0;
			foreach (AST childTree in m_children) {
				if(i > 0) { stringTree.Append(" "); }
				i++;
				stringTree.Append(childTree.getTreeAsString());
			}
			if ( !isNil() ) {
				stringTree.Append(")");
			}
			return stringTree.ToString();
		}
		
		Token m_token;
		List<AST> m_children;
	}
}

